package com.carrot.newsgallery.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.carrot.newsgallery.common.R;
import com.carrot.newsgallery.entity.*;
import com.carrot.newsgallery.mapper.EndorseArticleMapper;
import com.carrot.newsgallery.mapper.NewsFavorMapper;
import com.carrot.newsgallery.service.NewsChildService;
import com.carrot.newsgallery.service.NewsFavorService;
import com.carrot.newsgallery.service.NewsMainService;
import com.carrot.newsgallery.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;

@Slf4j
@Api(description = "用户收藏目录")
@RestController
@RequestMapping("/newsfavor")
public class NewsFavorController {

    @Autowired
    private NewsFavorService newsFavorService;
    @Autowired
    private NewsMainService newsMainService;
    @Autowired
    private NewsChildService newsChildService;
    @Autowired
    private EndorseArticleMapper endorseArticleMapper;
    @Autowired
    private NewsFavorMapper newsFavorMapper;

    @GetMapping("/getpage/{currentPage}/{pageSize}")
    @ApiOperation("分页查询用户本人的收藏夹")
    public R getPage(HttpServletRequest request,
                     @PathVariable int currentPage, @PathVariable int pageSize){
        String token = HttpUtil.getToken(request);
        TokenUtil tokenUtil = new TokenUtil();
        int userid = tokenUtil.getUserId(token);

        //构造查询器
        LambdaQueryWrapper<NewsFavor> lqw = new LambdaQueryWrapper<NewsFavor>();
        lqw.eq(true,NewsFavor::getUserId,userid);
        IPage<NewsFavor> page = new Page<NewsFavor>(currentPage, pageSize);

        return R.success(newsFavorMapper.selectPage(page,lqw),"查询成功");
    }

    @GetMapping("/getpage/{currentPage}/{pageSize}/{targetUserId}")
    @ApiOperation("分页查询其他用户公开的收藏夹")
    public R getPage(HttpServletRequest request,
                     @PathVariable int currentPage, @PathVariable int pageSize,
                     @PathVariable int targetUserId){

        //构造查询器
        LambdaQueryWrapper<NewsFavor> lqw = new LambdaQueryWrapper<NewsFavor>();
        lqw.eq(true,NewsFavor::getIsShared,1);
        lqw.eq(true,NewsFavor::getIsBanned,0);
        lqw.eq(true,NewsFavor::getUserId,targetUserId);
        //分页组件
        IPage<NewsFavor> page = new Page<NewsFavor>(currentPage, pageSize);

        return R.success(newsFavorMapper.selectPage(page,lqw),"查询成功");
    }

    /**
     * 这个方法要额外创造一个新的请求参数newsId来提供news在所在榜单中的id
     * @param request
     * @param hubIdentity
     * @param newsId
     * @return
     */
    @PostMapping()
    @ApiOperation("收藏一条新闻")
    public R saveFavor(HttpServletRequest request,
                       @RequestParam String hubIdentity,
                       @RequestParam int newsId){
        String token = HttpUtil.getToken(request);
        TokenUtil tokenUtil = new TokenUtil();
        int userid = tokenUtil.getUserId(token);


        NewsFavor newsFavor = new NewsFavor();
        //获取新闻来源代码
        if (hubIdentity.equals("news_main")){
            NewsMain news = newsMainService.getById(newsId);
            newsFavor.setUserId(userid);
            newsFavor.setTitle(news.getTitle());
            newsFavor.setSource(news.getSource());
            newsFavor.setRanking(news.getRank());
            newsFavor.setHref(news.getHref());
            newsFavor.setGatherDate(news.getCreateDate());
            newsFavor.setFavorDate(LocalDateTime.now());
            newsFavor.setIsShared(0);
            newsFavor.setIsBanned(0);
            newsFavor.setNote("# Hello!");
        }
        else {
            //设置查询的表名
            NewsChildTableNameParser.setIdentity(hubIdentity);
            NewsChild news = newsChildService.getById(newsId);
            newsFavor.setUserId(userid);
            newsFavor.setTitle(news.getTitle());
            newsFavor.setSource(news.getSource());
            newsFavor.setRanking(news.getRank());
            newsFavor.setHref(news.getHref());
            newsFavor.setGatherDate(news.getCreateDate());
            newsFavor.setFavorDate(LocalDateTime.now());
            newsFavor.setIsShared(0);
            newsFavor.setIsBanned(0);
            newsFavor.setNote("# Hello!");
        }

        if (newsFavorService.save(newsFavor))
            return R.success(null,"收藏成功");
        else
            return R.fail(ReturnCode.SERVER_ERROR,"服务器异常,请稍后重试");

    }

    @DeleteMapping("/cancle")
    @ApiOperation("取消收藏")
    public R cancleFavor(HttpServletRequest request,
                         @RequestParam int newsFavorId){
        String token = HttpUtil.getToken(request);
        TokenUtil tokenUtil = new TokenUtil();
        int userid = tokenUtil.getUserId(token);

        //确认收藏是否存在
        NewsFavor exist = newsFavorService.getById(newsFavorId);
        if (exist == null)
            return R.fail(ReturnCode.DATA_ERROR,"该收藏已不存在,请尝试刷新");
        //确认用户修改的目标是否为自己的笔记
        if (exist.getUserId()!=userid)
            return R.fail(ReturnCode.USER_ILLEGAL_OPERATION,"请勿尝试删除他人收藏!");

        if (newsFavorService.removeById(newsFavorId)){
            return R.success(null,"删除成功");
        }
        return R.fail(ReturnCode.SERVER_ERROR,"服务器异常,请稍后重试");
    }

    /**
     * 需要特别注意isshared变量必须携带在请求参数中,否则就会被默认置为0
     * @param request
     * @param newsFavor
     * @return
     */
    @PutMapping("/modify")
    @ApiOperation("修改了tag或者笔记或者公开状态")
    public R modifyFavor(HttpServletRequest request,
                         @RequestBody NewsFavor newsFavor){
        String token = HttpUtil.getToken(request);
        TokenUtil tokenUtil = new TokenUtil();
        int userid = tokenUtil.getUserId(token);

        //确认收藏是否存在
        NewsFavor exist = newsFavorService.getById(newsFavor.getNewsFavorId());
        if (exist == null)
            return R.fail(ReturnCode.DATA_ERROR,"该收藏已不存在,请尝试刷新");
        //确认用户修改的目标是否为自己的笔记
        if (exist.getUserId()!=userid)
            return R.fail(ReturnCode.USER_ILLEGAL_OPERATION,"请勿尝试更新他人收藏!");

        //修改内容
        LambdaUpdateWrapper<NewsFavor> luw = new LambdaUpdateWrapper<>();
        luw.eq(true,NewsFavor::getNewsFavorId,newsFavor.getNewsFavorId())
                .set(true,NewsFavor::getMyTag,newsFavor.getMyTag())
                .set(true,NewsFavor::getNote,newsFavor.getNote())
                .set(true,NewsFavor::getIsShared,newsFavor.getIsShared())
                .set(newsFavor.getIsShared()==1,NewsFavor::getPublicizeDate,LocalDateTime.now());

        //如果将公开状态改为1,要将该新闻加入到论坛数据库
        //不需要改变什么,论坛板块直接找为1的就可以了

        //如果公开状态从1变为0,不需要删除评论

        if (newsFavorService.update(null,luw))
            return R.success(null,"更新成功");
        return R.fail(ReturnCode.SERVER_ERROR,"无法更新该数据,请确认您的操作对象!");
    }

    @PostMapping("/endorse")
    @ApiOperation("赞同一条笔记或取消")
    public R endorseFavor(HttpServletRequest request,
                          @RequestBody int newsFavorId) throws MyDatabaseException {
        String token = HttpUtil.getToken(request);
        TokenUtil tokenUtil = new TokenUtil();
        int userid = tokenUtil.getUserId(token);

        //先判断该用户是否已经赞过该文章
        LambdaQueryWrapper<EndorseArticle> lqw = new LambdaQueryWrapper<>();
        lqw.eq(true,EndorseArticle::getPosterId,userid)
                .eq(true,EndorseArticle::getArticleId,newsFavorId);
        EndorseArticle one = endorseArticleMapper.selectOne(lqw);

        //获取点赞数
        NewsFavor newsFavor = newsFavorService.getById(newsFavorId);
        int favorNum = newsFavor.getFavorNum();

        //如果该用户没有赞过,那么就给该文章赞数+1,并将该赞同录入数据库
        if (one == null){
            favorNum += 1;
            //录入赞同数据库
            EndorseArticle endorseArticle = new EndorseArticle();
            endorseArticle.setArticleId(newsFavorId);
            endorseArticle.setPosterId(userid);
            endorseArticleMapper.insert(endorseArticle);
        }
        //该用户已经点赞,那就要给赞数-1,并从数据库中删除
        else{
            favorNum -= 1;
            endorseArticleMapper.deleteById(one);
        }

        //更新文章的获赞数
        LambdaUpdateWrapper<NewsFavor> luw = new LambdaUpdateWrapper<>();
        luw.eq(true,NewsFavor::getNewsFavorId,newsFavorId)
                .set(true,NewsFavor::getFavorNum,favorNum);
        if (!newsFavorService.update(luw)) {
            throw new MyDatabaseException(MyDatabaseException.errorCode.FAILURE);
        }
        return R.success(favorNum,"操作成功");
    }

}
